# (1)
# 题目描述：
# 通过OpenCV读取一张图片，完成下面的操作
#
# (2)
# 题目要求：.
# ①　导入相关头文件
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# ②　读入一张图片并转为灰度图
# path = 'image/crops.png'
path = '../../../../large_data/CV2/exam/day13/crops.png'
gray = cv.imread(path, cv.IMREAD_GRAYSCALE)
spr = 2
spc = 3
spn = 0
plt.figure(figsize=(12, 6))


def my_show_image(img, title, trans=None, **kwargs):
    global spn
    spn += 1
    plt.subplot(spr, spc, spn)
    plt.title(title)
    if trans is not None:
        img = trans(img)
    plt.axis('off')
    plt.imshow(img, **kwargs)


my_show_image(gray, 'gray', cmap='gray')

# ③　将图像转变为二值图
ret, bin = cv.threshold(gray, 0, 255, cv.THRESH_OTSU + cv.THRESH_BINARY_INV)
my_show_image(bin, 'bin', cmap='gray')

# ④　设置合适的形态学核
kernel = np.ones((3, 3), dtype=np.float32)

# ⑤　完成形态学变换
# ⑥　迭代合适的次数
closing = cv.morphologyEx(bin, cv.MORPH_CLOSE, kernel, iterations=2)
my_show_image(closing, 'closing', cmap='gray')

# ⑦　进行距离变换
dist = cv.distanceTransform(closing, cv.DIST_L2, 3)
my_show_image(dist, 'dist', cmap='gray')

# ⑧　对距离变换后的图像进行二值化
# ⑨　距离变换参数设置合理
# ⑩　二值化后粘连的图像分离
ret, bin_dist = cv.threshold(dist, 0.5 * dist.max(), dist.max(), cv.THRESH_BINARY)
my_show_image(bin_dist, 'bin_dist', cmap='gray')

# 11　对二值化后的图像进行轮廓提取
cv.normalize(bin_dist, bin_dist, 0., 1., cv.NORM_MINMAX)
bin_dist = bin_dist.astype(np.uint8)
contours, hierarchy = cv.findContours(bin_dist, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
bg = np.zeros((*gray.shape, 3), dtype=np.uint8)
cv.drawContours(bg, contours, -1, (0, 255, 0), 2)
my_show_image(bg, 'contours', lambda x: cv.cvtColor(x, cv.COLOR_BGR2RGB))

# 12　统计轮廓的个数
print(f'统计轮廓的个数: {len(contours)}')

# 13　加入必要注释

# show all plotting
plt.show()
